<?php
/**
 * File containing the BRail_Ldap_UserQueryTool class.
 * @package BRail_Ldap
 */

/**
 * @package BRail_Ldap
 */
class BRail_Ldap_UserQueryTool
{
    /**
     * @var BRail_Ldap_Adapter $_ldapAdapter
     */
    private $_ldapAdapter = null;

    /**
     * @param BRail_Ldap_Adapter $ldapAdapter
     * @throws BRail_Ldap_Exception
     */
    public function __construct(BRail_Ldap_Adapter $ldapAdapter)
    {
        $this->_ldapAdapter = $ldapAdapter;
    }

    /**
     * Search in LDAP
     *
     * @param string $type
     * @param string $pattern
     * @return array
     * @throws BRail_Ldap_Exception
     */
    public function customSearch($type, $pattern)
    {
        if (empty($type) || empty($pattern)) {
            throw new BRail_Ldap_Exception(
                __METHOD__.' expects a search type and a pattern');
        }

        return $this->search($type . '=' . $pattern);
    }

    /**
     * Search with custom filter and return data from LDAP
     *
     * @param string $filter LDAP filter: &(givenname=Xav*)(sn=Van H*)
     * @return array
     */
    public function search($filter)
    {
        // All the field types that can be returned
        $fields = array(
            'memberof', 'sn', 'givenname', 'displayname', 'telephonenumber',
            'physicaldeliveryofficename', 'cn', 'userprincipalname', 'whencreated',
            'whenchanged', 'homedirectory', 'mail', 'company', 'department',
            'distinguishedname'
        );

        $results = $this->_ldapAdapter->execute($filter, $fields);

        $returnArray = array();

        for ($i = 0; $i < $results['count']; $i++) {
            $entry = $results[$i];
            $groups = array();
            if (isset($entry['memberof'])) {
                // This loop parses all the memberOf entries returned by the LDAP ('memberOf: CN=Groupname,OU=xxx'),
                // in order to extract group names, which are added to the $groups[] array.
                for ($j = 0; $j < $entry['memberof']['count']; $j++) {
                    $groups[] = substr($entry['memberof'][$j], 3, strpos($entry['memberof'][$j], ',') - 3);
                }
            }
            $returnArray[] = new BRail_Ldap_Entry(
                isset($entry['sn'][0]) ? $entry['sn'][0] : null,
                isset($entry['givenname'][0]) ? $entry['givenname'][0] : null,
                isset($entry['displayname'][0]) ? $entry['displayname'][0] : null,
                isset($entry['telephonenumber'][0]) ? $entry['telephonenumber'][0] : null,
                isset($entry['physicaldeliveryofficename'][0]) ? $entry['physicaldeliveryofficename'][0] : null,
                isset($entry['cn'][0]) ? $entry['cn'][0] : null,
                isset($entry['userprincipalname'][0]) ? $entry['userprincipalname'][0] : null,
                isset($entry['whencreated'][0]) ? $entry['whencreated'][0] : null,
                isset($entry['whenchanged'][0]) ? $entry['whenchanged'][0] : null,
                isset($entry['homedirectory'][0]) ? $entry['homedirectory'][0] : null,
                isset($entry['mail'][0]) ? $entry['mail'][0] : null,
                isset($entry['company'][0]) ? $entry['company'][0] : null,
                isset($entry['department'][0]) ? $entry['department'][0] : null,
                isset($entry['distinguishedname'][0]) ? $entry['distinguishedname'][0] : null,
                $groups
            );
        }
        return $returnArray;
    }

    /**
     * @param string $value
     * @return array
     */
    public function searchByName($value)
    {
        return $this->customSearch('sn', $value);
    }

    /**
     * @param string $value
     * @return array
     */
    public function searchByFirstname($value)
    {
        return $this->customSearch('givenName', $value);
    }

    /**
     * @param string $value
     * @return array
     */
    public function searchByFullName($value)
    {
        return $this->customSearch('displayName', $value);
    }

    /**
     * @param string $value
     * @return array
     */
    public function searchByOffice($value)
    {
        return $this->customSearch('physicalDeliveryOfficeName', $value);
    }

    /**
     * @param string $value
     * @return array
     */
    public function searchByLogin($value)
    {
        return $this->customSearch('sAMAccountName', $value);
    }

    /**
     * @param string $ident
     * @return string
     */
    public static function getLoginByIdent($ident)
    {
        return BRail_User::getLoginByIdent($ident);
    }
}
